/*
*********************************************************************************************************
*	模块名称：
*	文件名称： .c
*	说明备注：无
*	修改记录：无
*	版本号     日期          作者     说明
*	V1.0       22-8-1      	 贾元文	 
*	Copyright by JIA
*********************************************************************************************************
*/
///////////////////////////////////////////////////////////
/*头文件包含区*/
#include "stm32f10x.h"
#include "hcsr04.h"
#include "sys.h"
#include "delay.h"
///////////////////////////////////////////////////////////
/*宏定义区*/

///////////////////////////////////////////////////////////
/*外部变量声明区*/
uint16_t mscount=0;//毫秒计数
///////////////////////////////////////////////////////////
/*函数声明区*/
void Timer4_TurnOnOn(void);
void Timer4_TurnOnOff(void);
int GetEcho_time(void);
void TRIG_Send(unsigned char lv);
 
///////////////////////////////////////////////////////////
/*函数实体区*/
/**********************************************************************************************************
* 函 数 名: TRIG_Send
* 功能说明: TRIG信号引脚控制，完成高低电平输出
* 形 参：unsigned char lv: 0电平、1高电平
* 返 回 值: 无
**********************************************************************************************************/
void TRIG_Send(unsigned char lv)
{
	if(lv==1)
		GPIO_SetBits(GPIOB,GPIO_Pin_11);
	else
		GPIO_ResetBits(GPIOB,GPIO_Pin_11);
}
/**********************************************************************************************************
* 函 数 名: HCSR04_init
* 功能说明: HCSR04超声波模块初始化
* 形 参：无
* 返 回 值: 无
**********************************************************************************************************/
void HCSR04_init(void)
{
	  GPIO_InitTypeDef GPIO_hcsr04init;				//超声波时钟结构体初始化
	  TIM_TimeBaseInitTypeDef TIM_hcsr04init;	//定时器时钟结构体初始化
	  NVIC_InitTypeDef NVIC_hcsr04init;				//定时器中断结构体初始化
	
	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);					//中断定时器优先级分组

	  //1.打开时钟
	  RCC_APB2PeriphClockCmd(ECHO_TRIG_GPIO_RCC_PORT,ENABLE);	//打开GPIO时钟
	  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);			//打开定时器时钟
	
	  //2.配置GPIO时钟
	  //Trig PB11 输出端 高电平
	  GPIO_hcsr04init.GPIO_Mode  = GPIO_Mode_Out_PP;	//推挽输出
	  GPIO_hcsr04init.GPIO_Pin   = GPIO_Pin_11;				//引脚11
	  GPIO_hcsr04init.GPIO_Speed = GPIO_Speed_50MHz;	//速度为50Mhz
	      
	  GPIO_Init(GPIOB,&GPIO_hcsr04init);				//配置GPIO初始化函数
	
	  //Echo PB10 输入端 
	  GPIO_hcsr04init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;		//浮空输入
	  GPIO_hcsr04init.GPIO_Pin   = GPIO_Pin_10;	//引脚10
	  GPIO_Init(GPIOB,&GPIO_hcsr04init);				//配置GPIO初始化函数
	   
	  //3.配置定时器结构体
		TIM_hcsr04init.TIM_ClockDivision = TIM_CKD_DIV1;			//不分频
		TIM_hcsr04init.TIM_CounterMode   = TIM_CounterMode_Up;//计数模式为向上计数
		TIM_hcsr04init.TIM_Period        = 100-1;	//重装载值为99
		TIM_hcsr04init.TIM_Prescaler     = 72-1;	//分频系数为71
		
	  TIM_TimeBaseInit(TIM4,&TIM_hcsr04init);		//配置定时器初始化函数
		TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);	//使能定时器中断
		TIM_Cmd(TIM4,DISABLE);										//失能定时器
		
	   
	  //4.配置定时器中断结构体
		NVIC_hcsr04init.NVIC_IRQChannel     =  TIM4_IRQn;				//配置通道4
		NVIC_hcsr04init.NVIC_IRQChannelCmd  =  ENABLE;					//使能定时器中断
		NVIC_hcsr04init.NVIC_IRQChannelPreemptionPriority  = 0;	//抢占优先级为0
		NVIC_hcsr04init.NVIC_IRQChannelSubPriority         = 0;	//子优先级为0
		 
		NVIC_Init(&NVIC_hcsr04init);//配置中断初始化
	
}
/**********************************************************************************************************
* 函 数 名: Timer4_TurnOn
* 功能说明: 定时器开启
* 形 参：无
* 返 回 值: 无
**********************************************************************************************************/
void Timer4_TurnOn(void)
{
		TIM_SetCounter(TIM4,0);
	  mscount=0;
	  TIM_Cmd(TIM4,ENABLE);
}
/**********************************************************************************************************
* 函 数 名: Timer4_TurnOnOff
* 功能说明: 定时器关闭
* 形 参：无
* 返 回 值: 无
**********************************************************************************************************/
void Timer4_TurnOnOff(void)
{
		TIM_Cmd(TIM4,DISABLE);
}
/**********************************************************************************************************
* 函 数 名: TIM4_IRQHandler
* 功能说明: 定时器中断处理函数
* 形 参：无
* 返 回 值: 无
**********************************************************************************************************/
void TIM4_IRQHandler(void)
{
		if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
		{
				 TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//清除中断标志位
				 mscount++;
		}
}
/**********************************************************************************************************
* 函 数 名: GetEcho_time
* 功能说明: 获取定时器的数值
* 形 参：无
* 返 回 值: 无
**********************************************************************************************************/
int GetEcho_time(void)
{
		uint32_t t=0;
	  t=mscount*1000;							//中断时间
	  t+= TIM_GetCounter(TIM4);		//得到定时器计数时间
	  TIM4->CNT=0;								//重装载值为0
	  delay_ms(50);								//延迟50ms
	  return t;
}
/**********************************************************************************************************
* 函 数 名: Get_Distance
* 功能说明: 超声波获取距离长度
* 形 参：无
* 返 回 值: 获取的距离长度,单位mm
**********************************************************************************************************/
float Get_Distance(void)
{
	 int i=0;										//定义次数i
	 uint32_t t=0;							//定义时间t
	 float length=0; 						//定义长度length
	 float sum=0;								//距离求和
	 while(i!=5)								//发送5次超声波
	 {
			TRIG_Send(1);						//发送超声波
		  delay_us(20);						//发送20us
		  TRIG_Send(0);						//停止发送超声波
	
		  while(ECHO_Reci==0);		//当超声波发出后
			Timer4_TurnOn();				//打开定时器
		  i=i+1; 									//次数加一
			
			while(ECHO_Reci==1);		//当收到超声波返回信号
			Timer4_TurnOnOff();			//关闭定时器
			t=GetEcho_time();				//获取定时器计数数值
		  length=((float)t/58.0);	//计算出距离长度
		  sum=sum+length;					//距离长度求和
			
	 }
	 length=sum/5.0;						//计算距离平均值
	 return length;							//返回距离长度
}
 
///////////////////////////////////////////////////////////
